//
//  GameViewController.m
//  BeatPlane
//
//  Created by LZXuan on 15-5-6.
//  Copyright (c) 2015年 轩哥. All rights reserved.
//

#import "GameViewController.h"
#import "Plane.h"
#import "Bullet.h"
#import "Enemy.h"

#import <AVFoundation/AVFoundation.h>


#define kScreenSize [UIScreen mainScreen].bounds.size
#define kBulletNumber 30


@interface GameViewController ()
{
    //游戏界面背景
    UIImageView *_backImageView;
    UIImageView *_backgroundView2;
    
    Plane *_plane;
    
    //定时器
    NSTimer *_timer;
    //方向视图
    UIView *_towardsView;
    //存放子弹
    NSMutableArray *_bulletArr;
    
    //敌人数组
    NSMutableArray *_enemyArr;
   
    //音频播放对象地址
    AVAudioPlayer *_player;
    
    //是否点在飞机上
    BOOL _isPlanePoint;
    
}
@end


@implementation GameViewController
- (void)dealloc {
    
    [_player release];
    [_enemyArr release];
    [_bulletArr release];
    [_towardsView release];
    [_backImageView release];
    [_backgroundView2 release];
    [super dealloc];
}

//代码入口
- (void)viewDidLoad {
    [super viewDidLoad];
    [self gameInit];
}
/*
 游戏界面 就是来管理游戏的
 管理 飞机 敌人 子弹
 */

/*
 1.创建背景
 2.设计飞机
 3.设计方向按钮 控制飞机移动
 4.飞机发射子弹 -> 循环利用 /复用
 5.设计敌人 敌人移动
 6.碰撞检测
 7.其他  声音  爆炸效果
 
 
 
 */

#pragma mark - 游戏初始化
- (void)gameInit {
    //先创建背景
    [self creatGameBack];
    
    [self creatEnemys];
    //创建飞机
    [self creatPlane];
    //创建方向
    [self creatTowardsView];
    //创建子弹
    [self creatBullets];
    //音乐
    [self creatBackgroundMusic];
}
#pragma mark - UITouch
//UIResponder 可以接收处理触摸事件

//UIView 或者 UIViewController 的父类UIResponder
//UIView 或者 UIViewController要想处理 屏幕的触摸 那么 需要重写父类的touches方法就可以了


#if 1
    //飞机跟着手指一起移动
#pragma mark - 手指点击屏幕的时候
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    //1.获取触摸
    UITouch *myTouch = [touches anyObject];
    CGPoint curP = [myTouch locationInView:self.view];
    
    //检测 一个点是否在 frame 上
    if (CGRectContainsPoint(_plane.frame, curP)) {
        _isPlanePoint = YES;
    }else {
        _isPlanePoint = NO;
    }
    
    
}
#pragma mark - 手指在屏幕移动的时候调用
//移动过程中一直调用
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    //NSLog(@"移动");
    if (!_isPlanePoint) {
        //刚开始点不在飞机上
        return;
    }
    
    //1.获取触摸
    UITouch *myTouch = [touches anyObject];
    //2.获取当前的位置
    CGPoint cur = [myTouch locationInView:self.view];
    //3.获取上一次移动触摸的位置
    CGPoint prePoint = [myTouch previousLocationInView:self.view];
    //算出偏移量
    CGFloat offSetX = cur.x-prePoint.x;
    CGFloat offSetY = cur.y-prePoint.y;
    
    //更改飞机的位置
    CGRect frame = _plane.frame;
    frame.origin.x += offSetX;
    frame.origin.y += offSetY;
    _plane.frame = frame;
    
    
}
//手指离开屏幕的时候调用
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    _isPlanePoint = NO;
}

//触摸被取消的时候调用 (比如电话来了)
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    _isPlanePoint = NO;
    NSLog(@"触摸被取消");
}


#else

#pragma mark - 手指开始点击屏幕的时候调用
//点击屏幕 飞机飞到指定位置
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"手指开始点击屏幕");
    //1.获取触摸
    UITouch *mytouch = [touches anyObject];
    //2.获取触摸的位置(相对于 self.view的位置)
    CGPoint curPoint = [mytouch locationInView:self.view];
    //更改飞机的中心点位置
    _plane.center = curPoint;
}
#endif



#pragma mark - 背景音乐
/*
 首先 把 音频素材 导入代码工程 add files...
 运行程序之后 会把音频 拷贝到app得沙盒的包内
 
 
 播放声音 可以用音频播放对象
 AVAudioPlayer
 1.
 xcode6之前 需要 导入AVFoundation.framework
 xcode6之后 不用 导入AVFoundation.framework
 
 2.导入头文件AVAudioPlayer在这个AVFoundation框架中
 #import <AVFoundation/AVFoundation.h>
 
 3.创建 AVAudioPlayer
 
 
 */
- (void)creatBackgroundMusic {
    //1.获取音频在app沙盒的包内的路径
    NSString *path = [[NSBundle mainBundle] pathForResource:@"game_music" ofType:@"mp3"];
    //NSLog(@"%@",path);
    //2.把本地NSString 路径 转化为 NSURL
    NSURL *url = [NSURL fileURLWithPath:path];
    //3.创建对象
    _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    //4.设置播放器
    //准备播放
    [_player prepareToPlay];
    //播放
    [_player play];
    //设置播放次数  0表示1次 负数表示无限次
    _player.numberOfLoops = -1;
}



#pragma mark - 界面将要显示的时候
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    //创建定时器
    [self creatTimer];
}
//界面将要离开屏幕的时候调用
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if ([_timer isValid]) {//判断定时器是否有效
        [_timer invalidate];//终止定时器
        _timer = nil;
    }
}


#pragma mark - 定时器
//定时器 控制器 飞机的移动 敌人的移动 子弹移动 碰撞检测
- (void)creatTimer {
    if (_timer) {
        [_timer invalidate];//销毁
        _timer = nil;
    }
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(timerClick) userInfo:nil repeats:YES];
}
#pragma mark - 定时器 触发的方法
- (void)timerClick {
    //控制飞机的移动
    [_plane planeAction];
    //子弹飞
    [self bulletFly];
    
    [self enemysMove];
    //碰撞检测
    [self isHitting];
    //背景移动
    [self backGroundMove];
}
#pragma mark - 碰撞检测
- (void)isHitting {
    //检测子弹和敌人是否有碰撞
    for (Bullet *bullet in _bulletArr) {
        //子弹在屏幕外不用检测
        if (bullet.frame.origin.y <= - bullet.frame.size.height) {
            continue;//遍历下一个子弹
        }
        //遍历所有的敌人
        for (Enemy *enemy in _enemyArr) {
            //碰撞检测
            //检测两个frame 有没有交集
            bool ret = CGRectIntersectsRect(bullet.frame, enemy.frame);
            if (ret) {
                //碰撞
                //放在屏幕外 就看不到了
                [enemy bomb];
                
                //另起一个线程执行 移除敌人的操作
                //让enemy延迟 0.2s执行resetFrame
                //爆炸 时间需要0.2s 0.2s之后我们才能让敌人离开屏幕
                [enemy performSelector:@selector(resetFrame) withObject:nil afterDelay:0.2];
                
                
                bullet.frame = CGRectMake(-50, -50, bullet.frame.size.width, bullet.frame.size.height);
            }
        }
    }
}

#pragma mark - 创建敌人
- (void)creatEnemys {
    _enemyArr = [[NSMutableArray alloc] init];
    
    for (NSInteger i = 0; i < 10; i++) {
        Enemy *enemy = [[Enemy alloc] init];
        [self.view addSubview:enemy];
        [_enemyArr addObject:enemy];
        [enemy release];
    }
}
//所有敌人移动  定时器控制
- (void)enemysMove{
    for (Enemy *enemy in _enemyArr) {
        [enemy moveDown];
    }
}


#pragma mark - 创建子弹
- (void)creatBullets {
    _bulletArr = [[NSMutableArray alloc] init];
    
    for (NSInteger i = 0; i < kBulletNumber; i++) {
        //把子弹先放在外面
        Bullet *bullet = [[Bullet alloc] initWithFrame:CGRectMake(-50, -50, 17, 17)];
        [self.view addSubview:bullet];
        //放入数组
        [_bulletArr addObject:bullet];
        [bullet release];
    }
}
#pragma mark - 子弹飞
//定时器控制
- (void)bulletFly {
    static int i = 0;
    
    //子弹 总共kBulletNumber要循环利用
    //如果子弹频繁的创建和销毁 性能会有影响
    //要降低子弹的发射频率 否则就是一条线
    
    if(_plane.isFire) {
        //当前函数调用5次 发射一颗子弹
        if (i % 5==0) {
            //开火状态 重置子弹的位置
            Bullet *bullet = _bulletArr[i/5];
            //重置到飞机的位置 发射位置
            [bullet resetFrame];
        }

        i++;
        if (i == kBulletNumber*5) {
            i = 0;//30个子弹用完 应该把再获取原来的第0个 循环利用
        }
    }
    
    //让所有子弹飞(不管子弹在哪里)
    for (Bullet *bullet in _bulletArr) {
        [bullet moveUp];
    }
}



#pragma mark - 创建方向按钮
- (void)creatTowardsView {
    //方向视图
    _towardsView = [[UIView alloc] initWithFrame:CGRectMake(0, kScreenSize.height-50, 150, 50)];
    _towardsView.backgroundColor = [UIColor clearColor];
    //粘贴到画布
    [self.view addSubview:_towardsView];
    
    //创建方向按钮 把方向按钮粘到 _towardsView上
    NSArray *imageNames = @[@"button_left",@"button_right"];
    for (NSInteger i = 0; i < imageNames.count; i++) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(100*i, 0, 50, 50);
        //设置图片
        [button setBackgroundImage:[UIImage imageNamed:imageNames[i]] forState:UIControlStateNormal];
        button.tag = 301+i;//设置tag 值
        //增加事件
        //按下 改变飞机的方向
        [button addTarget:self action:@selector(changeToward:) forControlEvents:UIControlEventTouchDown];
        //抬起的时候 停止飞机移动
        [button addTarget:self action:@selector(stopPlane) forControlEvents:UIControlEventTouchUpInside];
        [button addTarget:self action:@selector(stopPlane) forControlEvents:UIControlEventTouchUpOutside];
        [_towardsView addSubview:button];
    }
    
    //创建发射按钮
    UIButton *fireButton = [UIButton buttonWithType:UIButtonTypeCustom];
    fireButton.frame = CGRectMake(50, 0, 50, 50);
    [fireButton setBackgroundImage:[UIImage imageNamed:@"fire.png"] forState:UIControlStateNormal];
    [fireButton addTarget:self action:@selector(fireButton:) forControlEvents:UIControlEventTouchUpInside];
    [_towardsView addSubview:fireButton];
    
}
- (void)fireButton:(UIButton *)button {
    if (_plane.isFire) {
        //判断是否正在发射子弹
        _plane.isFire = NO;
        [button setBackgroundImage:[UIImage imageNamed:@"fire"] forState:UIControlStateNormal];
        [_plane stopPlaying];
        
    }else{
        _plane.isFire = YES;
        [button setBackgroundImage:[UIImage imageNamed:@"stop"] forState:UIControlStateNormal];
        //开始播放
        [_plane startPlaying];
    }
}

#pragma mark - 方向按钮控制的方法
- (void)changeToward:(UIButton *)button {
    switch (button.tag) {
        case 301://左移
            //控制飞机方向
            [_plane startMoveLeft];
            break;
        case 302://右移
            //控制飞机方向
            [_plane startMoveRight];
            break;
            
        default:
            break;
    }
}
- (void)stopPlane {
    //停止移动
    [_plane stopMoveing];
}


#pragma mark - 创建飞机
- (void)creatPlane {
    _plane = [Plane defaultPlane];
    //粘贴到画布
    [self.view addSubview:_plane];
}

- (void)creatGameBack {
    _backImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kScreenSize.width, kScreenSize.height+10)];
    _backImageView.image = [UIImage imageNamed:@"backgroud.png"];
    //粘贴到画布
    [self.view addSubview:_backImageView];
    
    //两张背景
    _backgroundView2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, -kScreenSize.height, kScreenSize.width, kScreenSize.height+10)];
    _backgroundView2.image = [UIImage imageNamed:@"backgroud.png"];
    [self.view addSubview:_backgroundView2];
    
}
#pragma mark - 游戏背景移动
- (void)backGroundMove {
    CGRect frame1 = _backImageView.frame;
    CGRect frame2 = _backgroundView2.frame;
    
    if (frame1.origin.y < kScreenSize.height) {
        frame1.origin.y += 4;
    }else {
        frame1.origin.y = -kScreenSize.height;
    }
    if (frame2.origin.y < kScreenSize.height) {
        frame2.origin.y += 4;
    }else {
        frame2.origin.y = -kScreenSize.height;
    }
    
    _backImageView.frame = frame1;
    _backgroundView2.frame = frame2;
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
